/* @formatter:off
 * Copyright (c) 2011 Lucas <lucas03093@gmail.com>
 * 
 * 
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
/* @formatter:on */

package nu.korkad.daytracker.activity;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.UnknownHostException;

import nu.korkad.daytracker.R;
import nu.korkad.daytracker.alertdialog.Changelog;
import nu.korkad.daytracker.info.AppInfo;
import nu.korkad.daytracker.info.Network;
import nu.korkad.daytracker.info.Notify;
import nu.korkad.daytracker.settings.Config;
import nu.korkad.daytracker.settings.PrefStore;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.ToggleButton;

import com.bugsense.trace.BugSenseHandler;
import com.dropbox.client2.DropboxAPI;
import com.dropbox.client2.android.AndroidAuthSession;
import com.dropbox.client2.session.AccessTokenPair;
import com.dropbox.client2.session.AppKeyPair;

public class Settings extends Activity
{
    private EditText                       settings_text_company_name;
    private EditText                       settings_text_deviceid;
    private ToggleButton                   settings_togglebutton_wifionly;
    private ToggleButton                   settings_togglebutton_notification;
    private ToggleButton                   settings_togglebutton_crashreport;
    // private ToggleButton settings_togglebutton_autoupdate;
    private ToggleButton                   settings_togglebutton_autoexport;
    private Button                         settings_button_dropbox_login;
    private Button                         settings_button_dropbox_logout;
    private ProgressBar                    settings_progressbar_updateinfo;
    private TextView                       settings_text_updateinfo;
    private Context                        context;
    public static String                   companyName;
    public static String                   deviceId;
    private DropboxAPI<AndroidAuthSession> mDBApi;
    
    @Override
    protected void onPause()
    {
        super.onPause();
        
        companyName = settings_text_company_name.getText().toString();
        deviceId = settings_text_deviceid.getText().toString();
    }
    
    @Override
    protected void onResume()
    {
        super.onResume();
        
        // Set dropbox keys if authorized
        if (mDBApi != null && mDBApi.getSession().authenticationSuccessful())
            try
            {
                mDBApi.getSession().finishAuthentication();
                
                AccessTokenPair tokens = mDBApi.getSession().getAccessTokenPair();
                
                PrefStore.setDropboxKey(this, tokens.key);
                PrefStore.setDropboxSecret(this, tokens.secret);
                
                // Update buttons
                settings_button_dropbox_login.setEnabled(false);
                settings_button_dropbox_login.setVisibility(View.GONE);
                settings_button_dropbox_logout.setEnabled(true);
                settings_button_dropbox_logout.setVisibility(View.VISIBLE);
            }
            catch (IllegalStateException e)
            {
                //System.out.println(e.getMessage());
            }
    }
    
    /** Called when the activity is first created. */
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        
        // Set layout
        setContentView(R.layout.activity_settings);
        
        // Crash report
        if (PrefStore.getCrashReport(this))
            BugSenseHandler.setup(this, Config.APPLICATION_BUGSENSE);
        
        // Get UI stuff
        context = this;
        settings_text_company_name = (EditText) findViewById(R.id.layout_settings_input_company_name);
        settings_text_deviceid = (EditText) findViewById(R.id.layout_settings_input_deviceid);
        settings_text_updateinfo = (TextView) findViewById(R.id.layout_settings_text_updateinfo);
        settings_togglebutton_wifionly = (ToggleButton) findViewById(R.id.layout_settings_togglebutton_wifionly);
        settings_togglebutton_notification = (ToggleButton) findViewById(R.id.layout_settings_togglebutton_notification);
        settings_togglebutton_crashreport = (ToggleButton) findViewById(R.id.layout_settings_togglebutton_crashreport);
        // settings_togglebutton_autoupdate = (ToggleButton) findViewById(R.id.layout_settings_togglebutton_autoupdate);
        settings_togglebutton_autoexport = (ToggleButton) findViewById(R.id.layout_settings_togglebutton_autoexport);
        settings_button_dropbox_login = (Button) findViewById(R.id.layout_settings_button_dropbox_login);
        settings_button_dropbox_logout = (Button) findViewById(R.id.layout_settings_button_dropbox_logout);
        settings_progressbar_updateinfo = (ProgressBar) findViewById(R.id.layout_settings_progressbar_update);
        
        // Set current stuff
        settings_text_company_name.setText(PrefStore.getCompanyName(this));
        settings_text_deviceid.setText(PrefStore.getDeviceId(this));
        settings_togglebutton_wifionly.setChecked(PrefStore.getWifiOnly(this));
        settings_togglebutton_notification.setChecked(PrefStore.getNotification(this));
        settings_togglebutton_crashreport.setChecked(PrefStore.getCrashReport(this));
        // settings_togglebutton_autoupdate.setChecked(PrefStore.getAutoUpdate(this));
        settings_togglebutton_autoexport.setChecked(PrefStore.getAutoExport(this));
        
        // Update dropbox buttons to their correct state
        if (PrefStore.getDropboxKey(this).equals(""))
        {
            settings_button_dropbox_login.setEnabled(true);
            settings_button_dropbox_logout.setEnabled(false);
            settings_button_dropbox_logout.setVisibility(View.GONE);
        }
        else
        {
            settings_button_dropbox_login.setEnabled(false);
            settings_button_dropbox_login.setVisibility(View.GONE);
            settings_button_dropbox_logout.setEnabled(true);
        }
    }
    
    /**
     * Toggles notification setting.
     * 
     * @param v
     */
    public void toggleNotification(View v)
    {
        if (PrefStore.getNotification(this))
            PrefStore.setNotification(this, false);
        else
            PrefStore.setNotification(this, true);
    }
    
    /**
     * Toggles wifi only setting.
     * 
     * @param v
     */
    public void toggleWifiOnly(View v)
    {
        if (PrefStore.getWifiOnly(this))
            PrefStore.setWifiOnly(this, false);
        else
            PrefStore.setWifiOnly(this, true);
    }
    
    /**
     * Toggles crash report setting.
     * 
     * @param v
     */
    public void toggleCrashReport(View v)
    {
        if (PrefStore.getCrashReport(this))
            PrefStore.setCrashReport(this, false);
        else
            PrefStore.setCrashReport(this, true);
    }
    
    /**
     * Toggles the auto update setting.
     * 
     * @param v
     */
    public void toggleAutoUpdate(View v)
    {
        if (PrefStore.getAutoUpdate(this))
            PrefStore.setAutoUpdate(this, false);
        else
            PrefStore.setAutoUpdate(this, true);
    }
    
    /**
     * Toggles the auto export setting.
     * 
     * @param v
     */
    public void toggleAutoExport(View v)
    {
        if (PrefStore.getAutoExport(this))
            PrefStore.setAutoExport(this, false);
        else
            PrefStore.setAutoExport(this, true);
    }
    
    public void dropboxLogin(View v)
    {
        if (PrefStore.getDropboxKey(this).equals(""))
        {
            // Get dropbox stuff
            AppKeyPair appKeys = new AppKeyPair(Config.DROPBOX_APP_KEY, Config.DROPBOX_APP_SECRET);
            AndroidAuthSession session = new AndroidAuthSession(appKeys, Config.DROPBOX_ACCESS_TYPE);
            mDBApi = new DropboxAPI<AndroidAuthSession>(session);
            
            // Check if user is authenticated against dropbox
            mDBApi.getSession().startAuthentication(this);
        }
    }
    
    public void dropboxLogout(View v)
    {
        if (!PrefStore.getDropboxKey(this).equals(""))
        {
            // Remove Dropbox acess keys from prefstore
            PrefStore.setDropboxKey(this, "");
            PrefStore.setDropboxSecret(this, "");
            
            mDBApi = null;
            
            // Update buttons
            settings_button_dropbox_login.setEnabled(true);
            settings_button_dropbox_login.setVisibility(View.VISIBLE);
            settings_button_dropbox_logout.setEnabled(false);
            settings_button_dropbox_logout.setVisibility(View.GONE);
        }
    }
    
    /**
     * Start the updater.
     * 
     * @param v
     */
    public void checkUpdates(View v)
    {
        // Check for networks
        if (Network.networkCheck(this).equals("ok"))
            // Start new thread to download updateinfo
            new DownloadUpdateInfo().execute(getString(R.string.update_url));
        else
            settings_text_updateinfo.setText(Network.networkCheck(this));
    }
    
    private class DownloadUpdateInfo extends AsyncTask<String, Void, String[]>
    {
        @Override
        protected void onPreExecute()
        {
            // Set appropriate values to show the user we're working
            settings_progressbar_updateinfo.setVisibility(View.VISIBLE);
            settings_text_updateinfo.setText(getString(R.string.layout_settings_text_updateinfo_inprogress));
            settings_text_updateinfo.setVisibility(View.VISIBLE);
        }
        
        @Override
        protected String[] doInBackground(String... urls)
        {
            // Variables
            String updateVersionCode = "";
            String updateVersionName = "";
            String updateChangelog = "";
            String updateURL = "";
            String status = "";
            String statusReason = "";
            int statusCode = 0;
            
            // Setup http stuff
            DefaultHttpClient client = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(urls[0]);
            
            try
            {
                // Download update info
                HttpResponse execute = client.execute(httpGet);
                InputStream content = execute.getEntity().getContent();
                
                // Status code
                statusCode = execute.getStatusLine().getStatusCode();
                statusReason = execute.getStatusLine().getReasonPhrase();
                
                // If statusCode is 200 read update info
                if (statusCode == 200)
                {
                    // Read the data to appropriate Strings
                    BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
                    
                    // Read update info
                    updateVersionCode = buffer.readLine();
                    updateVersionName = buffer.readLine();
                    updateChangelog = "* " + buffer.readLine();
                    updateURL = buffer.readLine();
                    
                    // Format changelog
                    updateChangelog = updateChangelog.replace("<br>", "\n* ");
                    
                    // Set status to ok
                    status = "ok";
                    
                    // Debug stuff
                    // System.out.println("Version code: " + updateVersionCode);
                    // System.out.println("Version name: " + updateVersionName);
                    // System.out.println("Changelog: " + updateChangelog);
                    // System.out.println("Status: " + status);
                }
                else
                    // Set error message
                    status = statusCode + " " + statusReason;
            }
            catch (ClientProtocolException e)
            {
                status = getString(R.string.layout_settings_text_updateinfo_exception_clientprotocol) + " " + e.getMessage();
            }
            catch (UnknownHostException e)
            {
                status = getString(R.string.layout_settings_text_updateinfo_exception_unknownhost) + " " + e.getMessage();
            }
            catch (IOException e)
            {
                status = getString(R.string.layout_settings_text_updateinfo_exception_io) + " " + e.getMessage();
            }
            catch (IllegalStateException e)
            {
                status = getString(R.string.layout_settings_text_updateinfo_exception_illegalstate) + " " + e.getMessage();
            }
            
            // Return our findings
            return new String[] { status, updateVersionCode, updateVersionName, updateChangelog, updateURL };
        }
        
        @Override
        protected void onPostExecute(String[] result)
        {
            // Turn off the progress bar
            settings_progressbar_updateinfo.setVisibility(View.INVISIBLE);
            
            // Check for errors
            if (!result[0].equals("ok"))
                settings_text_updateinfo.setText(getString(R.string.layout_settings_text_updateinfo_fail) + "\n" + result[0]);
            // Check version code
            else if (!result[1].equals(Integer.toString(AppInfo.getVersionCode(context))))
            {
                // Send notification
                if (PrefStore.getNotification(context))
                {
                    Notify n = new Notify();
                    n.updateNotification(getString(R.string.noficication_update_title), getString(R.string.app_name),
                            getString(R.string.noficication_update_title) + " " + getString(R.string.notification_update_desc) + " "
                                    + result[2], result[4], context);
                }
                
                // Show dialog
                AlertDialog builder = Changelog.create(context, getString(R.string.dialog_update_button_download),
                        getString(R.string.dialog_update_button_dismiss), result[3], result[2], result[4]);
                builder.show();
                
                // Update text
                settings_text_updateinfo.setText(getString(R.string.layout_settings_text_updateinfo_available));
            }
            else
                settings_text_updateinfo.setText(getString(R.string.layout_settings_text_updateinfo_none));
        }
    }
}
